#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#define MAX_NUM 100000
#define MAX_ITEM 100
enum ItemValue { NUM,CHAR,FIN };
typedef int ElementType;
typedef struct STACK Stack;
typedef union ITEM{
	int Num;
	char Ch;
}Item;
struct STACK{
	ElementType Elm;
	Stack *Next;
};
//ItemValue GetNextItem(char*,Item;
_Bool IsBlank(char);
_Bool IsNum(char);
_Bool IsOptr(char);
int GetNextItem(char*,Item*,enum ItemValue*);
char * GetNextItem_2(char*,Item*,enum ItemValue*);
Stack *StackInit(void);
_Bool StackEmpty(Stack*);
_Bool StackFull(Stack*);
void  Push(Stack*,ElementType);
ElementType Pop(Stack*);
void  DestroyStack(Stack*);
int CalcExp(char *str);

int main(){
/*
	int i;
	char a[]="10 23 + 93 * 124 -   ";
	char *b=a;
	Item item;
	enum ItemValue iv;
	i=0;
	while( (b=GetNextItem_2(b,&item,&iv)) ){
sleep(1);
		printf("i:%-3d",i);
		if( iv == CHAR ){
			printf("Get Char:%c\n",item.Ch);
		}else
			printf("Get Num :%d\n",item.Num);
	}
	printf("End of String\n");
	//char a[]="1  2  + 2*3/";
*/
	char a[100];
	fgets(a,99,stdin);
	//for(int i=0;i<strlen(a);i++)printf("%c ",a[i]);
	printf("We Got:%s \n",a);
	printf("%d",CalcExp(a));
	return 0;
}

int CalcExp(char *str){
	int ret;
	Item it;
	enum ItemValue iv;
	Stack *s=StackInit();
	while( (str=GetNextItem_2(str,&it,&iv)) ){
		if( iv == CHAR ){
			int b=Pop(s);
			int a=Pop(s);
			switch(it.Ch){
				case '+':
					ret=a+b;
					break;
				case '-':
					ret=a-b;
					break;
				case '*':
					ret=a*b;
					break;
				case '/':
					ret=a/b;
					break;
			}
			Push(s,ret);
		}else if( iv == NUM ){
			Push(s,it.Num);
		}else{
		}
	}
	ret=Pop(s);
	//DestroyStack(s);
	return ret;
}

_Bool IsBlank(char ch){
	if( ch == ' ' || ch == '\n' \
		|| ch == '\t' )
		return true;
	return false;
}
_Bool IsNum(char ch){
	if( ch >= '0' && ch <= '9' )
		return true;
	return false;
}
_Bool IsOptr(char ch){
	if( '+' == ch || '-' == ch || '*' == ch || '/' == ch )
		return true;
	return false;
}
int GetNextItem(char *str,Item *item,enum ItemValue *iv){
	if( NULL == str )return -1;
	char c;
	char num[7];
	int count=0,sstate;
	while( (sstate=sscanf(str+count,"%c",&c)) != EOF && c == ' ' ){
		count++;
	}
	if( sstate == EOF ){
		return -1;
	}
	else if( '+' == c || '-' == c || '*' == c || '/' == c ){
		item->Ch=c;
		(*iv)=CHAR;
		return ++count;
	}else if( c >= '0' && c <= '9' ){		// 0 -----> 9
		int i=0;
		do{
			num[i++]=c;
			count++;
		}while( (sstate=sscanf(str+count,"%c",&c)) != EOF && c != ' ' );
		num[i]='\0';
		item->Num=atoi(num);
		(*iv)=NUM;
		return ++count;
	}else{
		return -1;
	}
}
char * GetNextItem_2(char *str,Item *item,enum ItemValue *iv){
	if( NULL == str )return NULL;
	int index=0,num_i=0;
	char c,num[7];
	_Bool find=false;
	while( sscanf(str+index,"%c",&c) != EOF ){
		index++;
		if( IsBlank(c) ){
			if( !find )
				continue;
			else{
				if( *iv == NUM ){
					num[num_i]='\0';
					item->Num=atoi(num);
					return str+index;
				}else
					return str+index;
			}
		}else if( IsNum(c) ){
			find=true;
			(*iv)=NUM;
			num[num_i++]=c;
		}else if( IsOptr(c) ){
			find=true;
			(*iv)=CHAR;
			item->Ch=c;
		}else{
			continue;
			//(*iv)=FIN;
			//break;
		}
	}
	(*iv)=FIN;
	return NULL;
}
Stack *StackInit(void){
	Stack *s=malloc(sizeof(Stack));
	s->Next=NULL;
	return s;
}
_Bool StackEmpty(Stack *s){
	if( s->Next )return false;
	return true;
}
//_Bool StackFull(Stack*);
void  Push(Stack *s,ElementType x){
	Stack *new=malloc(sizeof(Stack));
	new->Elm=x;
	new->Next=s->Next;
	s->Next=new;
	return ;
}
ElementType Pop(Stack *s){
	ElementType x=s->Next->Elm;
	Stack *tmp=s->Next;
	s->Next=s->Next->Next;
	free(tmp);
	return x;
}
void  DestroyStack(Stack *s){
	while( !StackEmpty(s) )Pop(s);
	free(s);
	return ;
}
